使用 Node.js 自創 API 部署到 heroku 並且 解決 cors

2021-07-16 Fri

以下是紀錄最簡易部署方式並非最好的做法,可能造成冗 code,僅作為操作筆記用。

  • 下載 Node.js
  • 下載 heroku cli

使用 terminal cd 到對應的資料夾 然後

  1. npm install express-generator -g
    建立一個 ejs 的 Node.js 名叫做 myapp 伺服器
  2. express --view=ejs myapp
    可以自己取名字不一定要叫 myapp
  3. cd myapp
    移動到該資料夾
  4. npm install

參見方法 express generator

注意 如果之前已經全域安裝過,也就是已經執行過 npm install exrpess-generator -g 的話就從第二步開始

建立一個 api 路由

在 routes 底下新建一個名叫做api.js(名稱可以自取)

複製index.js的內容到api.js 記得將router.get('/', function(req, res, next) { });的內容 改成 res.json();

意思是當有人存取這個路由的時候要回傳的內容 這邊定義為回傳 json 檔這邊先以物件 {id:1,name: 'Tom'}為例子

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.json(
    {
        id:1,
        name: 'Tom'
    }
  )
});
module.exports = router;

app.js的地方增加路由存取 如下第九行的地方和第二十五行的地方

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var apiRouter = require('./routes/api');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/api', apiRouter);


// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});
module.exports = app;

這個時候開啟terminal 使用cd指令到該資料夾

npm start 然後開啟瀏覽器localhost:3000/api

這時候應該能在瀏覽器看到圖如下

後來回來到 terminal 按下Ctrl+C來關閉伺服器

注意:每次更改該專案的程式碼的時候伺服器並不會自動更新,必須重啟,也就是在此重複以下動作 Ctrl+C再輸入npm start

fetch 遠端資料到本伺服器

1.開啟 postman 擷取遠端資料按下 send 後 2.再按下右邊 code 3.左邊選擇 Node.js axios 複製程式碼

回到routes的自創的那個api.js 撰寫對應的 function

宣告一個 data = []; 撰寫一個 function 然後把剛剛 postman 的 request 複製的 code 貼到 function 底下 在 if 的地方將 body 的內容轉成 JSON 的格式存到 data 如第 14 行

當使用者存取進來的時候以 json 格式則轉送 data 出去如第 21 行

var express = require('express');
var router = express.Router();
var axios = require('axios');
let data = [];
function getData(){
  var config = {
    method: 'get',
    url: 'https://od.cdc.gov.tw/eic/Day_Confirmation_Age_County_Gender_19CoV.json',
    headers: { }
  };
  axios(config)
  .then(function (response) {
    data = response.data
    console.log(JSON.stringify(response.data));
  })
  .catch(function (error) {
    console.log(error);
  });
}
getData();

router.get('/',function(req, res, next) {
    res.json(data);
});

module.exports = router;

注意 必須安裝npm install axios --save

才可以發送遠端 API 請求

接下來npm start在瀏覽器輸入localhost:3000/api應該就可以看到對應的物件

部署到 heroku

  • 到 heroku 的官網

  • 按下 new→create new app 如下圖

  • 取一個 app name 的名字

回到終端機,由於 heroku 是可以透過 git 指令建立遠端伺服器

接下來建立一個 git 連結遠端資料庫

  • 輸入git init
  • 輸入heroku git:remote -a <你的遠端資料庫名字>
  • 輸入git add .
  • 輸入git commit -m "你的該分支名字"

然後必須設定一個頭 git push --set-upstream heroku master 接下來的上傳改用 git push heroku master就可以了

之後回到瀏覽器做 fetch 會發現還沒有解決 cors 的問題

fetch('你的heroku/api網址')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(myJson);
  });

解決 cors 以便跨瀏覽器 fetch 資料

在 terminal 輸入npm install cors

更多可觀看文件 cors express node js

app.js加入 cors 開啟的語法 如第 11 行和第 23 行

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var apiRouter = require('./routes/api');

const cors = require('cors');
var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(cors());
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/api', apiRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

重新在終端機設置

git add . git commit -m "add cors"

然後git push heroku master

然後用瀏覽器 fecth 資料

fetch('你的API路由')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(myJson);
  });

就可以成功接回來了